package pacote;


public class Datagrama {
	private Integer versao = 6;
	private Integer classe_de_trafego = 0;
	private Integer identificador_de_fluxo = 0;
	private Integer tamanho_dos_dados = 0;
	private Integer proximo_cabecalho = 0;
	private Integer limite_de_encaminhamento = 0;
	private String dados;
	private Ip ip_origem;
	private Ip ip_destino;

	private int tamanho_versao = 4;
	private int tamanho_classe_de_trafego = 8;
	private int tamanho_identificador_de_fluxo = 20;
	private int tamanho_tamanho_dos_dados = 16;
	private int tamanho_proximo_cabecalho = 8;
	private int tamanho_limite_de_encaminhamento = 8;
	private int tamanho_ip = 128;
	private int tamanho_minimo_dados = 46;

	public Datagrama(){}
	
	public Datagrama(Ip end_origem, Ip end_destino, Integer tamanho_dos_dados,  String dados){
		this.tamanho_dos_dados = tamanho_dos_dados;
		this.ip_origem = end_origem;
		this.ip_destino = end_destino;
		this.dados = dados;
	}
	
	public String getDatagramaString(){
		String string_versao = Integer.toBinaryString(versao);
		String string_classe_de_trafego = Integer.toBinaryString(classe_de_trafego);
		String string_identificador_de_fluxo = Integer.toBinaryString(identificador_de_fluxo);
		String string_tamanho_dos_dados = Integer.toBinaryString(tamanho_dos_dados);
		String string_proximo_cabecalho = Integer.toBinaryString(proximo_cabecalho);
		String string_limite_de_encaminhamento = Integer.toBinaryString(limite_de_encaminhamento);
		String string_ip_origem = ip_origem.getIpBynaryString();
		String string_ip_destino = ip_destino.getIpBynaryString();
		String string_dados = new String();
		
		for(int i = 0; i < dados.length() ; i++){
			String string_dados_parcial = Integer.toBinaryString(dados.charAt(i));
			for(int j = string_dados_parcial.length(); j < 8; j++) string_dados_parcial = "0" + string_dados_parcial;

			string_dados += string_dados_parcial;
		}
		
		for(int i = string_versao.length() ; i < tamanho_versao ; i++) string_versao = '0'+ string_versao;
		for(int i = string_classe_de_trafego.length() ; i < tamanho_classe_de_trafego ; i++) string_classe_de_trafego = '0'+ string_classe_de_trafego;
		for(int i = string_identificador_de_fluxo.length() ; i < tamanho_identificador_de_fluxo ; i++) string_identificador_de_fluxo = '0'+ string_identificador_de_fluxo;
		for(int i = string_tamanho_dos_dados.length() ; i < tamanho_tamanho_dos_dados ; i++) string_tamanho_dos_dados = '0'+ string_tamanho_dos_dados;
		for(int i = string_proximo_cabecalho.length() ; i < tamanho_proximo_cabecalho ; i++) string_proximo_cabecalho = '0'+ string_proximo_cabecalho;
		for(int i = string_limite_de_encaminhamento.length() ; i < tamanho_limite_de_encaminhamento ; i++) string_limite_de_encaminhamento = '0'+ string_limite_de_encaminhamento;
		for(int i = string_ip_origem.length() ; i < tamanho_ip ; i++) string_ip_origem = '0'+ string_ip_origem;
		for(int i = string_ip_destino.length() ; i < tamanho_ip ; i++) string_ip_destino = '0'+ string_ip_destino;
		for(int i = string_dados.length() ; i < tamanho_minimo_dados ; i++) string_dados = '0'+ string_dados;
			
		
		StringBuilder datagrama = new StringBuilder();
		
		datagrama.append(string_versao);
		datagrama.append(string_classe_de_trafego);
		datagrama.append(string_identificador_de_fluxo);
		datagrama.append(string_tamanho_dos_dados);
		datagrama.append(string_proximo_cabecalho);
		datagrama.append(string_limite_de_encaminhamento);
		datagrama.append(string_ip_origem);
		datagrama.append(string_ip_destino);
		datagrama.append(string_dados);

		return datagrama.toString();
	}
	
	public void stringToDatagrama(String datagramaBinarioString){
		versao = Integer.parseInt(datagramaBinarioString.substring(0, 4), 2);
		classe_de_trafego = Integer.parseInt(datagramaBinarioString.substring(4, 12), 2);
		identificador_de_fluxo = Integer.parseInt(datagramaBinarioString.substring(12, 32), 2);
		tamanho_dos_dados = Integer.parseInt(datagramaBinarioString.substring(32, 48), 2);
		proximo_cabecalho = Integer.parseInt(datagramaBinarioString.substring(48, 56), 2);
		limite_de_encaminhamento = Integer.parseInt(datagramaBinarioString.substring(56, 64), 2);
		
		String string_ip_origem = datagramaBinarioString.substring(160, 192);
		Integer ip_numero_1 = Integer.parseInt(string_ip_origem.substring(0, 8), 2);
		Integer ip_numero_2 = Integer.parseInt(string_ip_origem.substring(8, 16), 2);
		Integer ip_numero_3 = Integer.parseInt(string_ip_origem.substring(16, 24), 2);
		Integer ip_numero_4 = Integer.parseInt(string_ip_origem.substring(24, 32), 2);
		string_ip_origem = ip_numero_1 + "." + ip_numero_2 + "." + ip_numero_3 + "." + ip_numero_4;
		ip_origem = new Ip(string_ip_origem);
		
		String string_ip_destino = datagramaBinarioString.substring(288, 320);
		ip_numero_1 = Integer.parseInt(string_ip_destino.substring(0, 8), 2);
		ip_numero_2 = Integer.parseInt(string_ip_destino.substring(8, 16), 2);
		ip_numero_3 = Integer.parseInt(string_ip_destino.substring(16, 24), 2);
		ip_numero_4 = Integer.parseInt(string_ip_destino.substring(24, 32), 2);
		string_ip_destino = ip_numero_1 + "." + ip_numero_2 + "." + ip_numero_3 + "." + ip_numero_4;
		ip_destino = new Ip(string_ip_destino);
		
		String dados_binario = datagramaBinarioString.substring(320, 320 + tamanho_dos_dados);
		dados = new String();
		for(int i = 0; i < dados_binario.length(); i += 8){
		    int k = Integer.parseInt(dados_binario.substring(i, i+8), 2);
		    dados += (char) k;
		} 
	}
	
	public Integer getTamanho_dos_dados() {
		return tamanho_dos_dados;
	}

	public void setTamanho_dos_dados(Integer tamanho_dos_dados) {
		this.tamanho_dos_dados = tamanho_dos_dados;
	}
	
	public Integer getVersao() {
		return versao;
	}

	public void setVersao(Integer versao) {
		this.versao = versao;
	}

	public Integer getClasse_de_trafego() {
		return classe_de_trafego;
	}

	public void setClasse_de_trafego(Integer classe_de_trafego) {
		this.classe_de_trafego = classe_de_trafego;
	}

	public Integer getIdentificador_de_fluxo() {
		return identificador_de_fluxo;
	}

	public void setIdentificador_de_fluxo(Integer identificador_de_fluxo) {
		this.identificador_de_fluxo = identificador_de_fluxo;
	}

	public Integer getProximo_cabecalho() {
		return proximo_cabecalho;
	}

	public void setProximo_cabecalho(Integer proximo_cabecalho) {
		this.proximo_cabecalho = proximo_cabecalho;
	}

	public Integer getLimite_de_encaminhamento() {
		return limite_de_encaminhamento;
	}

	public void setLimite_de_encaminhamento(Integer limite_de_encaminhamento) {
		this.limite_de_encaminhamento = limite_de_encaminhamento;
	}

	public String getDados() {
		return dados;
	}

	public void setDados(String dados) {
		this.dados = dados;
	}

	public Ip getIp_origem() {
		return ip_origem;
	}

	public void setIp_origem(Ip ip_origem) {
		this.ip_origem = ip_origem;
	}

	public Ip getIp_destino() {
		return ip_destino;
	}

	public void setIp_destino(Ip ip_destino) {
		this.ip_destino = ip_destino;
	}
}
